import React from "react";

export default class Demo extends React.Component { //定义组件，组件首字母大写（“状态state”通常会统一交由父组件通过“方法”进行管理，父组件“方法”通常会交由子组件进行调用）
    constructor(props) {//构造函数。其中，props主要用于实现数据与方法的共享，接收组件中传递过来的属性信息（HashMap，可以是数据，也可以是方法），使用方式为this.props，只读不可修改。如要实现组建内部的数据（即状态，state）的存储与共享，应使用this.state
        super(props);
        this.state = {
            users: [] //设置数据初始值
        };
    }

    /**
     * 约定方法，生命周期，组件加载结束时调用，简单理解，render之后调用（componentWillMount, componentDidMount, componentWillReceiveProps, componentWillUpdate, componentDidUpdate, componentWillUnmount）
     */
    componentDidMount = () => {
        console.log("组件加载（结束）--->componentDidMount");
        this.loadUsersFromServer();
    }

    /**
     * 约定方法，部分其他生命周期展示
     */
    componentWillMount = () => {
        console.log("组件加载（开始）--->componentWillMount");
    }
    componentWillUpdate = () => {
        console.log("组件更新（开始）--->componentWillUpdate");
    }
    componentDidUpdate = () => {
        console.log("组件更新（结束）--->componentDidUpdate");
    }

    //自定义普通方法，从数据库中读取用户列表
    loadUsersFromServer = () => {
        fetch('http://localhost/user/index').then((response) => {
            return response.json(); //此返回值将传给下一个then的参数（data）,简单理解，等同于JSON.parse(response.text())
        }).then((data) => {
            console.log("用户列表(users)：");
            console.log(data);

            this.setState({
                users: data //设置状态同时更新dom
            });
        });
    }

    // 自定义普通方法，创建用户。当前写法的好处是：不用绑定this（this.createUser = this.createUser.bind(this);）
    createUser = (user) => {
        fetch('http://localhost/user/save', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(user)
        }).then((response) => {
            this.loadUsersFromServer();
        })
    }

    // 自定义普通方法，删除用户
    deleteUser = (user) => {
        console.log(user.id);
        let data = new FormData()
        data.append("id", user.id)

        fetch ("http://localhost/user/delete", {
            method: 'POST',
            body:data
        }).then((response) => {
            this.loadUsersFromServer();
        })
    }

    render() {
        return (
            <div className="container" style={{paddingTop:30}}>
                <UserForm createUser={this.createUser}/> {/*把创建方法传到子组件里*/}
                <br/>
                <UserTable deleteUser={this.deleteUser} users={this.state.users}/> {/*把删除方法传到子组件里，同时传入的还有用户列表*/}
            </div>
        );
    }
}

class UserForm extends React.Component { //表单，用于创建用户
    constructor(props) {
        super(props);

        console.log("表单默认值(defaultProps)：");
        console.log(props);

        this.state = {username: props.username, password: props.password, realname: props.realname}; //传入默认值
    }

    //定义props默认值
    static defaultProps = {
        username: 'lvchanglong',
        password: '123456',
        realname: '吕常龙'
    }

    //自定义事件处理方法，建议命名时，以handle开头
    handleChange = (event) => {
        console.log("NAME: " + event.target.name + " VALUE: " + event.target.value)
        this.setState(
            {[event.target.name]: event.target.value} //设置用户信息
        );
    }

    //自定义事件处理方法
    handleSubmit = (event) => {
        event.preventDefault(); //阻止默认事件
        console.log("提交: " + this.state.username + "-" + this.state.password + "-" + this.state.realname);

        const {username, password, realname} = this.state; //简单理解，批量定义
        console.log("扩展: " + username + "-" + password + "-" + realname);

        let newUser = {'username': this.state.username, "password": this.state.password, realname: this.state.realname}; //收集新用户信息
        this.props.createUser(newUser); //创建新用户
    }

    render() {
        return (
            <div className="panel panel-default">
                <div className="panel-body">
                    <form className="form-inline">
                        <div className="col-md-3">
                            <input type="text" placeholder="账号" className="form-control"  name="username" onChange={this.handleChange}/>
                        </div>
                        <div className="col-md-3">
                            <input type="text" placeholder="密码" className="form-control" name="password" onChange={this.handleChange}/>
                        </div>
                        <div className="col-md-3">
                            <input type="text" placeholder="姓名" className="form-control" name="realname" onChange={this.handleChange}/>
                        </div>
                        <div className="col-md-3">
                            <button className="btn btn-success" onClick={this.handleSubmit}>保存</button>
                        </div>
                    </form>
                </div>
            </div>
        );
    }
}

class UserTable extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        let users = this.props.users.map(user => //数据渲染，把普通数据转化映射成拥有指定格式的数据
            <User key={user.id} deleteUser={this.props.deleteUser} user={user}/> //传入删除方法，同时传入用户
        );

        return (
            <div>
                <table className="table table-striped">
                    <thead>
                    <tr>
                        <th>账号</th><th>密码</th><th>姓名</th><th>操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {users}
                    </tbody>
                </table>
            </div>
        );
    }
}

class User extends React.Component {
    constructor(props) {
        super(props);
    }

    //自定义事件处理方法
    handleDelete = (event) => {
        this.props.deleteUser(this.props.user); //删除此用户
    }

    render() {
        return (
            <tr>
                <td>{this.props.user.username}</td>
                <td>{this.props.user.password}</td>
                <td>{this.props.user.realname}</td>
                <td>
                    <button className="btn btn-danger" onClick={this.handleDelete}>删除</button>
                </td>
            </tr>
        );
    }
}